# -*- coding: utf-8 -*-
import os
from urllib.parse import quote

from django.http import HttpResponse
from openpyxl.utils import get_column_letter
from openpyxl.workbook import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
from openpyxl.styles import Font, colors, Alignment, PatternFill
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action

from dvadmin.system.models import FileList
from dvadmin.design.models import Flow, NodeTypes, NodesHierarchy
from dvadmin.design.views.hierarchy import NodesHierarchySerializer
from dvadmin.utils.json_response import DetailResponse, ErrorResponse, SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet
from dvadmin.system.views.file_list import FileSerializer
from dvadmin.utils import graphwalker


class FlowSerializer(CustomModelSerializer):
    """
    序列化器
    """

    class Meta:
        model = Flow
        fields = "__all__"


class FlowViewSet(CustomModelViewSet):
    """
    流程图 接口
    list:查询
    save:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = Flow.objects.all()
    serializer_class = FlowSerializer

    def create(self, request, *args, **kwargs):

        name = request.data.get('name')
        node_type = request.data.get('node_type')

        instance = NodeTypes.objects.filter(description='testmodel').first()
        if instance is None:
            return ErrorResponse(msg="查询出错")

        parent = NodesHierarchy.objects.filter(name=name, node_order=0, node_type=instance, parent=None).first()
        if parent is not None:
            return ErrorResponse(msg="名称已存在")

        # Hierarchy新增1条testmodel，作为根节点
        data_hier = {"name": name, "node_order": 0, "node_type": instance.id, "parent": None}
        serializer = NodesHierarchySerializer(data=data_hier, request=request)
        serializer.is_valid(raise_exception=True)
        parent = serializer.save()

        instance = NodeTypes.objects.filter(description=node_type).first()
        if instance is None:
            return ErrorResponse(msg="查询出错")

        # Hierarchy新增1条model detail，作为枝节点
        data_hier = {"name": name, "node_order": 0, "node_type": instance.id, "parent": parent.id}
        serializer = NodesHierarchySerializer(data=data_hier, request=request)
        serializer.is_valid(raise_exception=True)
        hierarchy = serializer.save()

        serializer = FileSerializer(data=request.data, request=request)
        serializer.is_valid(raise_exception=True)
        file_list = serializer.save()

        data = {"name": name, "status": True, "file_list_id": file_list.id , "hierarchy": hierarchy.id}
        serializer = FlowSerializer(data=data, request=request)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return DetailResponse(msg="成功")

    def list(self, request, *args, **kwargs):

        is_superuser = request.user.is_superuser
        if is_superuser:
            queryset = Flow.objects.all().values_list("hierarchy")
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            queryset = Flow.objects.filter(dept_belong_id__in=dept_list).values_list("hierarchy")

        queryset = NodesHierarchy.objects.filter(id__in=queryset).values_list("parent")
        queryset = NodesHierarchy.objects.filter(id__in=queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = NodesHierarchySerializer(page, many=True, request=request)
            return self.get_paginated_response(serializer.data)
        serializer = NodesHierarchySerializer(queryset, many=True, request=request)
        return SuccessResponse(data=serializer.data, msg="成功")

    def retrieve(self, request, *args, **kwargs):

        pid = kwargs.get('pk')
        is_superuser = request.user.is_superuser
        if is_superuser:
            instance = NodesHierarchy.objects.filter(id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(parent_id=pid)
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            instance = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, parent_id=pid)
        filelist = Flow.objects.filter(status=1, hierarchy__in=hierarchy).values('file_list_id').first()
        queryset = FileList.objects.filter(id=filelist['file_list_id']).first()

        data = {"id": instance.id, "name": instance.name, "file_url": queryset.file_url, "file_name": queryset.name, "file_id": queryset.id, "file_size": queryset.size}
        return DetailResponse(data=data, msg="成功")

    @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
    def gen(self, request, *args, **kwargs):
        """根据测试模型生成测试场景  """

        pid = request.query_params.get('id')
        is_superuser = request.user.is_superuser
        if is_superuser:
            instance = NodesHierarchy.objects.filter(id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(parent_id=pid)
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            instance = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, parent_id=pid)
        filelist = Flow.objects.filter(status=1, hierarchy__in=hierarchy).values('file_list_id').first()
        queryset = FileList.objects.filter(id=filelist['file_list_id']).first()
        here = os.path.abspath(os.getcwd())
        full_path = os.path.join(here, queryset.file_url)
        res = list(graphwalker.walk(full_path))
        data = {"id": instance.id, "name": instance.name}
        page = self.paginate_queryset(res)
        if page is not None:
            data["testsuite"] = page
            return self.get_paginated_response(data)
        data = {"id": instance.id, "name": instance.name, "testsuite": res}
        return DetailResponse(data=data, msg="成功")

    @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
    def export(self, request, *args, **kwargs):
        """导出模型和场景 """

        pid = request.query_params.get('id')
        is_superuser = request.user.is_superuser
        if is_superuser:
            instance = NodesHierarchy.objects.filter(id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(parent_id=pid)
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            instance = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, parent_id=pid)
        response = HttpResponse(content_type="application/msexcel")
        response["Access-Control-Expose-Headers"] = f"Content-Disposition"
        response["content-disposition"] = f'attachment;filename={quote(str(f"导出{instance.name}.xlsx"))}'
        wb = Workbook()
        ws2 = wb.create_sheet(index=0, title='测试场景')

        filelist = Flow.objects.filter(status=1, hierarchy__in=hierarchy).values('file_list_id').first()
        queryset = FileList.objects.filter(id=filelist['file_list_id']).first()
        here = os.path.abspath(os.getcwd())
        full_path = os.path.join(here, queryset.file_url)
        data = list(graphwalker.walk(full_path))

        title2 = ['序号', '测试目的', "步骤"]
        row2 = get_column_letter(len(title2))
        column = 1
        ws2.append(title2)
        for index, testcase in enumerate(data):
            case_step = ''
            for h_index, val in enumerate(testcase):
                if val is None or val == "":
                    case_step += str(h_index+1) + '. ' + '\n'
                else:
                    case_step += str(h_index+1) + '. ' + val.replace('\n', '').strip() + '\n'
            ws2.append([index + 1, instance.name, case_step])
            column += 1
        # 　更新列宽
        for index in range(len(title2)):
            ws2.column_dimensions[get_column_letter(index + 2)].width = 30
        tab2 = Table(displayName="Table2", ref=f"A1:{row2}{column}")  # 名称管理器
        style = TableStyleInfo(
            name="TableStyleLight11",
            showFirstColumn=True,
            showLastColumn=False,
            showRowStripes=True,
            showColumnStripes=True,
        )

        tab2.tableStyleInfo = style
        ws2.add_table(tab2)
        wb.save(response)
        return response
